<template>
  <div class="all-select">
    <a-tree-select
      v-model:value="selectedOptions"
      :tree-data="options"
      dropdownClassName="all-global-select"
      :allowClear="!disabledSelect"
      multiple
      :disabled="disabledSelect"
      :maxTagCount="maxTagCount"
      :field-names="{
        label: 'channelName',
        value: 'channelCode',
        children: 'children'
      }"
      treeNodeFilterProp="channelName"
      showCheckedStrategy="SHOW_ALL"
      @change="selectChange"
      placeholder="请选择"
      :virtual="virtualValue"
      style="width: 100%"
    >
    </a-tree-select>
  </div>
</template>
<script lang="ts" setup>
import type { PropType } from 'vue'
import { reactive, computed, nextTick, onMounted } from 'vue'
import { cloneDeep } from 'lodash-es'
import { ALL_SELECT } from '@/utils/constantMap'

const props = defineProps({
  options: {
    type: Array as PropType<any[]>,
    default: () => []
  },
  selectValue: {
    type: Array as PropType<any[]>,
    default: () => []
  },
  maxTagCount: {
    type: Number as PropType<number>,
    default: 10
  },
  virtualValue: {
    type: Boolean as PropType<boolean>,
    default: false
  },
  disabledSelect: {
    type: Boolean as PropType<boolean>,
    default: false
  }
})

const emit = defineEmits(['update:selectValue'])

const selectedOptions = computed({
  get() {
    return props.selectValue
  },
  set(value: string[]) {
    emit('update:selectValue', value)
  }
})

const selectObj = reactive<any>({
  oldChooseData: []
})

function getChannelCode(options: any, arr: any) {
  options.forEach((item: any) => {
    arr.push(item.channelCode)
    if (item.children && item.children.length > 0) {
      getChannelCode(item.children, arr)
    }
  })
}
// 勾选变化
const selectChange = (val: string[]) => {
  const allValues: any[] = []
  getChannelCode(props.options, allValues)
  console.log('选项数据====>', allValues)
  // 用来储存上一次选择的值，可进行对比
  const oldVal = selectObj.oldChooseData.length > 0 ? selectObj.oldChooseData : []

  // 若选择全部
  if (val.includes(ALL_SELECT)) {
    selectedOptions.value = allValues
  }

  // 取消全部选中。 上次有， 当前没有， 表示取消全选
  if (oldVal.includes(ALL_SELECT) && !val.includes(ALL_SELECT)) {
    selectedOptions.value = []
  }

  // 点击非全部选中，需要排除全部选中 以及 当前点击的选项
  // 新老数据都有全部选中
  if (oldVal.includes(ALL_SELECT) && val.includes(ALL_SELECT)) {
    const index = val.indexOf(ALL_SELECT)
    val.splice(index, 1) // 排除全选选项
    selectedOptions.value = val
  }

  // 全选未选，但是其他选项都全部选上了，则全选选上
  if (!oldVal.includes(ALL_SELECT) && !val.includes(ALL_SELECT)) {
    if (val.length === allValues.length - 1) {
      selectedOptions.value = [ALL_SELECT].concat(val)
    }
  }

  // 储存当前选择的最后结果 作为下次的老数据
  nextTick(() => {
    selectObj.oldChooseData = cloneDeep(selectedOptions.value)
  })
  console.log('选择数据====>', val)
}

onMounted(() => {
  if (props.selectValue && props.selectValue.length) {
    selectChange(props.selectValue)
  }
})
</script>
<style lang="less" scoped>
.all-select {
  width: 100%;
}
</style>
